<!DOCTYPE html>
<html>
    
<head>
    <meta charset="utf-8">
    
    <title>聊聊 Android 开发的现状和思考 | ApocalypseBlog</title>
    <canvas id="header_canvas"style="position:absolute;bottom:0"></canvas> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    

    

    

    

    
<link rel="stylesheet" href="/dist/build.css?v=1.14.0.css">

    <script src="/javascripts/bubble.js"></script>
    <script>
        window.isPost = true
        window.aomori = {
            
            
        }
        window.aomori_logo_typed_animated = false
        window.aomori_search_algolia = false

    </script>
<script>
    ((window.gitter = {}).chat = {}).options = {
      room: 'ApocalypseBlog/Apocalypse'
    };
  </script>
  <script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer></script>
<meta name="generator" content="Hexo 5.3.0"></head>
<!--DaoVoice服务http://blog.daovoice.io/-->

    <script>(function (i, s, o, g, r, a, m) {
        i['DaoVoiceObject'] = r;
        i[r] = i[r] ||
          function () {
            (i[r].q = i[r].q || []).push(arguments);
          };
        i[r].l = 1 * new Date();
        a = s.createElement(o);
        m = s.getElementsByTagName(o)[0];
        a.async = 1;
        a.src = g;
        a.charset = 'utf-8';
        m.parentNode.insertBefore(a, m);
      })(window, document, 'script', ('https:' === document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/b00f5052.js", 'daovoice');
      daovoice('init', {
        app_id: "b00f5052",
      });
      daovoice('update');
    </script>
  
<body>

    <div class="container">
    <header class="header">
        <div class="header-type">
            
            <div class="header-type-inner">
                
                    <a class="header-type-title" href="/">ApocalypseBlog</a>
                
    
                
            </div>
        </div>
        <div class="header-menu">
            <div class="header-menu-inner">
                
            </div>
            <div class="header-menu-social">
                
            </div>
        </div>

        <div class="header-menu-mobile">
            <div class="header-menu-mobile-inner" id="mobile-menu-open">
                <i class="icon icon-menu"></i>
            </div>
        </div>
    </header>

    <div class="header-menu-mobile-menu">
        <div class="header-menu-mobile-menu-bg"></div>
        <div class="header-menu-mobile-menu-wrap">
            <div class="header-menu-mobile-menu-inner">
                <div class="header-menu-mobile-menu-close" id="mobile-menu-close">
                    <i class="icon icon-cross"></i>
                </div>
                <div class="header-menu-mobile-menu-list">
                    
                </div>
            </div>
        </div>
    </div>

</div>

    <div class="container">
        <div class="main">
            <section class="inner">
                <section class="inner-main">
                    <div class="post">
    <article id="post-ckk6o6ava000l7knyev0ff2el" class="article article-type-post" itemscope
    itemprop="blogPost">

    <div class="article-inner">

        
          
        
        
        

        
        <header class="article-header">
            
  
    <h1 class="article-title" itemprop="name">
      聊聊 Android 开发的现状和思考
    </h1>
  

        </header>
        

        <div class="article-more-info article-more-info-post hairline">

            <div class="article-date">
  <time datetime="2020-06-28T15:51:51.000Z" itemprop="datePublished">2020-06-28</time>
</div>

            

            

            

        </div>

        <div class="article-entry post-inner-html hairline" itemprop="articleBody">
            <p>回想这六年里 Android 开发的发展历程，现如今的 Android 已经拥有了成熟的开发体系，技术框架也是经历了一代一代的更新：</p>
<ul>
<li><code>HttpClient</code>、<code>Volley</code> 、<code>OkHttp</code>、<code>Retrofit</code> ；</li>
<li><code>ImageLoader</code>、<code>Picasso</code>、<code>Fresco</code>、<code>Glide</code>；</li>
<li><code>OrmLite</code>、<code>LitePal</code>、<code>GreenDao</code>、<code>Realm</code>、<code>Room</code>；</li>
</ul>
<p>除了熟悉的网络、图片和数据库“三大件”外，还有像 <code>xUtils</code>、<code>EventBus</code>、<code>Dagger</code>、<code>RxJava</code>、<code>MultiType</code> 等等，它们对于老 Android 来说，可以说是贯穿了整个“青春期”的回忆。</p>
<a id="more"></a>

<p><img src="http://user-gold-cdn.xitu.io/2020/6/22/172dc0dcf8786462?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p>从一开始的 <code>MVC</code> 到 <code>MVP</code> 再到 <code>MVVM</code> 乃至官方提供的 <code>AAC</code> 架构，Android 的技术栈一直在“刷新”，而随着 Kotlin 的扶正还有 Android Jetpack 的提出，新一代的完善开发体系也给老开发们带来了一些额外的“烦躁”。</p>
<blockquote>
<p>“AS 2.3 又不是不能用？！”</p>
<p>”项目还要继续兼容 4.4 版本？！！”</p>
<p>“RxJava 都还没用上就开始吹协程？！！！”</p>
</blockquote>
<p>因为旧项目的维护或者工作环境的影响，很多时候其实没有新框架落地的条件，甚至于 Flutter 的出现都会被贩卖一波焦虑。</p>
<p><strong>那就让我们聊聊这种焦虑或者不安。放心，后面没有“防不胜防”！</strong></p>
<h3 id="“没用过”的焦虑"><a href="#“没用过”的焦虑" class="headerlink" title="“没用过”的焦虑"></a>“没用过”的焦虑</h3><p>对于老 Android 来说，<strong>有一种“焦虑”情绪来自于“我还没用过”</strong>，因为新生的框架和技术在不断迭代，而“没有用过就跟不上时代”的情绪，会在每次技术更新迭代时被反复放大，这大概就是部分 Android 焦虑的来源。</p>
<blockquote>
<p>例如现在的 <code>Android Jetpack</code>、协程、 <code>Jetpack Compose</code> 、<code>Flutter</code> 等，每次看到这些字眼时就会莫名地出现“焦虑”，犹如当年一开始听到 <code>Dagger</code>、<code>RxJava</code> 、<code>React Native</code> 一样。</p>
</blockquote>
<p><strong>那要怎么样缓（tao）解（bi）这种焦虑呢？这就要先理解下这些“新技术”名词不断出现地原因，我把这种“我还没用过”的焦虑理解为“扳手升级副作用”。</strong></p>
<p>这里举一个有趣的例子，如下图所示是不同阶段扳手，可以看到：</p>
<ul>
<li>从 1 到 2 用户拧螺母需要准备的扳手数量减少了；</li>
<li>从 2 到 3 扳手变得更加帅气有力，并且附带的“攻击力”也有所上升；</li>
</ul>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/22/172db286d28a2381?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p>那问题来了：</p>
<p>一、既然有 2 这样便捷的扳手，那 1 这种扳手还有必要存在吗？</p>
<ul>
<li><strong>答案是有的，因为 1 中的扳手性价比更高，在特点的场景下会更轻便。</strong></li>
</ul>
<p>二、那扳手 2 既然都满足大部分场景了，扳手 3 有必要存在吗？</p>
<ul>
<li><strong>答案也是有的，因为 3 中的扳手更加帅气，同时从健壮的角度更可靠。</strong></li>
</ul>
<p>这里扯了这两个问题其实是想表达：<strong>正在情况下随着技术的发展，新生框架和技术是为了让开发变成更便捷，同时降低开发门槛方便后来者入坑。</strong></p>
<p>所以作为老 Android 开发，<strong>在经历了开发项目需要准备“一堆扳手”的手动挡时代，如今在这个只要一个“扳手”就能干活的半自动挡时代，怎么可能会拧不动螺母？</strong></p>
<p>过去的日子我们拧了无数的螺母，现在只不过要需要换个“扳手”，而这个扳手是可能是 3 ，第一次拿起来也许会“太重”，扭动的开关也不熟练，但是曾经的螺母需要“拧多深”和“卡什么体位”，这些对我们来说其实和之前没太大区别。</p>
<p><strong>所以只要还是“拧螺母”，我们不应该因为担心“扳手”的品类太多而焦虑，或者还应该“庆幸”这个领域仍在健康发展。</strong></p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/22/172dc5c25c02f498?imageslim" alt="img"></p>
<p>技术的健康演进只会让它越来越容易被理解和使用，让开发的门槛变得越来越低：</p>
<ul>
<li>从 <code>RxJava1</code> 到 <code>RxJava2</code> 的变化；</li>
<li>从 <code>Dagger</code> 到现在官方的 <code>Koin</code>；</li>
<li>从 Java 的 <code>AsyncTask</code> 到 Kotlin 的协程；</li>
<li>从 <code>ButterKnife</code> 到 <code>KTX</code> ；</li>
</ul>
<p>所以用新的”扳手”肯定比用旧的一堆”扳手”方便，实际上开发者需要维护的代码和逻辑会越来越少，这是一个社区越来越成熟的表现，进而开发的门槛也就越来越低了。</p>
<p>而对于新技术的无法落地到项目的焦虑，我们可以换个思路：<strong>没有条件落地，但是可以去尝试理解这个新框架或技术的本质是什么，从而缓解对未知的恐惧。</strong></p>
<p>比如 <code>Dagger</code> 说白了就是基于注解和模板生成代码，所以如果看不懂各种”生涩”的注解，那可以直接看生成的代码，理解 <code>Dagger</code>  是如何用“臃肿”的代码来为我们解耦。</p>
<p>另外在接下来的 Android Studio 4.1 下，已经开始支持了 <code>Dagger</code> 类的直接跳转，我们可以轻松地在 Dagger 的关联代码间进行导航。</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/22/172db91d4764a3d2?imageslim" alt="img"></p>
<p><strong>所以换一个“扳手”的学习成本并不高，只要你扭螺母的功底还在</strong>。“现在还没用过”也不用慌，也许等等技术还能更成熟更方便学习，何况再等等还能白嫖大佬的文章不是么？</p>
<p>当然这里还有一个有趣的误解：</p>
<blockquote>
<p><strong>扳手 2 升级后比扳手 1 牛逼了，所以作为使用扳手 2 的我比使用扳手 1 的牛逼？</strong></p>
</blockquote>
<p>然而真相是：<strong>牛逼的是扳手的制造者，而作为使用者，直接使用 <code>OkHttp</code> 的可能还不如使用 <code>HttpClient</code> 的开发对网络请求的理解”深刻”。</strong></p>
<p>框架降低了开发的门槛，提高了代码的可维护性，但是作为使用者的我们在享受便捷的同时，要变牛逼的根本不在于用，而在于需要理解框架为什么好用！</p>
<p>比如 <code>OkHttp</code> 好用在于它优秀的拦截器设计，而 <code>Retrofit</code> 通过注解生成模板代码提高了开发效率，但是 <code>Retrofit</code> 本身网络请求部分还是需要 <code>OkHttp</code>等去支持。</p>
<blockquote>
<p>把框架优秀的部分吃下去，那么你才会变牛逼，<code>OkHttp</code> 的设计就在 Flutter 中就被 <code>Dio</code> 框架完美复现，而 <code>Dio</code> 框架也成为了 Flutter 下热门的网络请求封装之一。</p>
</blockquote>
<h3 id="竞争力的焦虑"><a href="#竞争力的焦虑" class="headerlink" title="竞争力的焦虑"></a>竞争力的焦虑</h3><p>还有一种就是竞争力的焦虑，我们时不时会把自己和年轻一代的开发们做比较，<strong>明显年轻人更便宜更耐C也更有体力</strong>，这让即将成为后浪的我们产生了职业生涯的焦虑。</p>
<p>因为开发体系的成熟带来了的门槛的降低，开发 Android 应用的要求确实没以前高，<strong>但是“能用”和“好用”那是两个故事！</strong></p>
<p>对比年轻人我们存在一些劣势，但是作为老开发在竞争力上还是有着一些其他的优势，比如：<strong>对业务的理解和落地能力</strong>。</p>
<p>简单举个例子，在 Android 上产品提出了一个需求：</p>
<blockquote>
<p>“增加一个播放功能，效果和爱奇艺差不多就行。”</p>
</blockquote>
<p>多么“合理”的需求，这时候“吃过盐”的老 Android 相信都会“心头一颤“，在心里默默“问候”产品的同时，开始思考开发前需要讨论的“坑位”：</p>
<ul>
<li>视频是否需要规定好编码格式，比如 <code>H264</code>/<code>AAC</code> 、<code>MPEG</code>/<code>MP3</code>？</li>
<li>封装协议用 <code>MP4</code> 还是 <code>M3U8</code>？</li>
<li>码率和帧率是否需要适应网络？</li>
<li>用软解码 <code>FFMPEG</code> 还是 <code>MediaCodec</code> ？</li>
<li>视频是否需要支持 <code>AES128</code> 加密？</li>
<li>本地是否要增加离线缓存？</li>
<li>是否要支持断线重连？</li>
<li>后续是否要支持直播和广告的拓展？</li>
</ul>
<p>虽说不考虑以上部分写的代码也能用，也有一些开源项目提供“保姆式”支持，但是当你遇到坑后还能不能继续推进项目，并且如何在项目周期内合理避坑，这些都很考验一个开发的综合能力。</p>
<p><strong>这个综合能力自然不只包括代码，而是需要时间慢慢去养成和踩坑来得到。</strong></p>
<p>是的，在我的角度而言开发不只是写代码，我们的竞争力也不只在于代码，比如业务落地的能力就是长期的经验累积而成，比如：</p>
<ul>
<li>一个工单的发起到结束流程会经历什么；</li>
<li>一个购物订单从发起到售后的流转需要考虑什么；</li>
<li>一个订房系统在并发时需要关注的什么；</li>
<li>一个直播系统需要怎么样的技术栈去支撑；</li>
</ul>
<p>这些业务在具体场景下需要面对哪些坑？为什么这个业务要这么写？甚至是你在知道这样设计是不合理的情况下，要如何组织代码去避免后期频繁修改带来的负担。</p>
<blockquote>
<p>毕竟好的代码千百万，坏的代码都是在业务高压下多次无情的修改摧残出来。</p>
</blockquote>
<p>瞎扯了这么多，其实就是想表达：<strong>作为普通人的我们，一般情况下技术并不会成为我们的壁垒，因为现在的 IT 行业很多岗位把脑力密集型变成了体力密集型，996和007需要体力，更需要圆滑的心态去站稳脚跟，年轻气盛的是少年，而行业经验能让我们更好地保存体力去面对职场的“风起云涌”</strong>。</p>
<blockquote>
<p>当然，如果职业几年来都是深水摸鱼，那也无 fuck 可说了～</p>
</blockquote>
<p>所以我也一直有个建议：<strong>在条件允许的情况下，尽量选择一个行业，不要今年搞教育、明年干餐饮、后年跳物联网这样跨界</strong>。</p>
<p>常年的“跨界”可能到哪都只是“大头兵”，一个行业内的人脉是资源，我们可能不擅长交际，但是我们一直说xxx圈子很小，或者我们能力不是特别出众，但是干的久了认识的圈内人也就多了。</p>
<p><strong>到了 35 岁之后，10年的电商行业经验或者会比 10 年的移动开发经验更有用一点点</strong>。</p>
<blockquote>
<p>当然这属于站着说要不腰疼，条件允许是指经济压力不大的情况下，不管什么狗屁理论，活下去就是第一要素。</p>
</blockquote>
<h3 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h3><p>回归主题，从 2018 Android 提出的 Jetpack 看，到了 2020 年的现在变化其实也不大，也就多了像 <code>ViewPager2</code> 、 <code>CameraX</code> 、<code>Motionlayout</code> 等的更新(最近还有 <code>Hilt</code>、<code>Paging 3</code>、<code>App Startup</code> )，并且在 Android 10 和 Android 11 开始着重隐私和<code>Scoped Storage</code> 分区等，这大概也是 Android 开发在趋向成熟和稳定的表现。</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/21/172d530f1b956396?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p><strong>所以 Android 现在已经拥有十分成熟的开发体系，成熟也说明了这个系统的带来的开发红利消退了，说通俗点就是可以跳槽岗位少了。</strong></p>
<p>而作为非技术大佬的我，就会选择一些其他的东西来尝试突破，比如前端、<code>RN</code>、<code>Flutter</code> 等其他技术领域做尝试。</p>
<p>当然每个人的理念和选择可能不同，也许我的方式就并不适合你，这里只是想表达一下：<strong>当你觉得自己处于“瓶颈”而焦虑时，或者可以选择从别的方向去折腾下。</strong></p>
<blockquote>
<p>另外友情提醒，不要给自己随便定计划，如要”周更多少文章”或者”月读多少书”，定了就要尽可能去完成，不然因为完成不了计划的“自作孽”而增加焦虑也是够够的。</p>
</blockquote>
<p>最后，这里大多属于一家之言，仅供参考，主要也是有感而发，希望能对你有点帮助，让开发的日常也能够继续安心摸鱼！</p>

        </div>

    </div>

    

    

    

    

    

    
<nav class="article-nav">
  
    <a href="/2020/06/30/%E5%B8%AE%E6%9C%8B%E5%8F%8B%E8%BD%AC%E5%8F%91%E4%B8%80%E4%B8%AA%E5%8D%9A%E5%AE%A2/" id="article-nav-newer" class="article-nav-link-wrap">
      <div class="article-nav-caption">下一篇</div>
      <div class="article-nav-title">
        
          帮朋友转发一个博客
        
      </div>
    </a>
  
  
    <a href="/2020/06/16/FragmentStatePagerAdapter%E5%9C%A8ViewPager%E4%B8%AD%E4%BC%98%E5%8C%96%E4%BA%86%E4%BB%80%E4%B9%88/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-caption">上一篇</div>
      <div class="article-nav-title">FragmentStatePagerAdapter在ViewPager中优化了什么</div>
    </a>
  
</nav>


    <section class="share">
        <div class="share-title">分享</div>
        <a class="share-item" target="_blank"
            href="https://twitter.com/share?text=聊聊 Android 开发的现状和思考 - ApocalypseBlog&url=http://example.com/2020/06/28/%E8%81%8A%E8%81%8A-Android-%E5%BC%80%E5%8F%91%E7%9A%84%E7%8E%B0%E7%8A%B6%E5%92%8C%E6%80%9D%E8%80%83/">
            <box-icon type='logo' name='twitter'></box-icon>
        </a>
        <a class="share-item" target="_blank"
            href="https://www.facebook.com/sharer.php?title=聊聊 Android 开发的现状和思考 - ApocalypseBlog&u=http://example.com/2020/06/28/%E8%81%8A%E8%81%8A-Android-%E5%BC%80%E5%8F%91%E7%9A%84%E7%8E%B0%E7%8A%B6%E5%92%8C%E6%80%9D%E8%80%83/">
            <box-icon name='facebook-square' type='logo' ></box-icon>
        </a>
        <!-- <a class="share-item" target="_blank"
            href="https://service.weibo.com/share/share.php?title=聊聊 Android 开发的现状和思考 - ApocalypseBlog&url=http://example.com/2020/06/28/%E8%81%8A%E8%81%8A-Android-%E5%BC%80%E5%8F%91%E7%9A%84%E7%8E%B0%E7%8A%B6%E5%92%8C%E6%80%9D%E8%80%83/&pic=">
            <div class="n-icon n-icon-weibo"></div>
        </a> -->
    </section>

</article>









</div>
                </section>
            </section>

             
            <aside class="sidebar">
            
                
            </aside>
        </div>
    </div>

    <footer class="footer">
    <div class="footer-wave">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#3c4859" fill-opacity="1" d="M0,160L60,181.3C120,203,240,245,360,240C480,235,600,181,720,186.7C840,192,960,256,1080,261.3C1200,267,1320,213,1380,186.7L1440,160L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path></svg>
    </div>

    <div class="footer-wrap">
        <div class="footer-inner"> 
            ApocalypseBlog &copy; 2021<br>
            Powered By Hexo · Theme By <a href="https://github.com/lh1me/hexo-theme-aomori" target="_blank">Aomori</a>
        </div>
    </div>

</footer>




<script src="/dist/build.js?1.14.0.js"></script>


<script src="/dist/custom.js?1.14.0.js"></script>









</body>

</html>